home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / expire.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  11KB  |  428 lines

  1. /* Expire old messages.
  2.  * Inspired by 'expire.c' by Bernie Roehl.
  3.  * Substantially rewritten for integration into KA9Q NOS,
  4.  * WG7J v1.01 and later
  5.  * by Johan. K. Reinalda, WG7J/PA3DIS, March/April 92
  6.  *
  7.  * Old bid expiry by WG7J, March 92
  8.  */
  9. /* 'expire n' sets the expire interval for n hours.
  10.  * Each time the timer goes off, a new process is started,
  11.  * that expires the old messages...
  12.  *
  13.  * The control file '~/spool/expire.dat' contains lists of
  14.  * filename age
  15.  * where 'filename' is the name of the .txt file under '~/spool/mail'
  16.  * containing the messages (without the .txt extension) and where
  17.  * age = maximum age of message in days.
  18.  *
  19.  * If no age is given, the default age is 21 days.
  20.  *
  21.  * filename can be extended into subdirectories, and can have either
  22.  * '/', '\' or '.' to indicate subdirectories.
  23.  * filename should NOT have the ending '.txt'
  24.  */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #ifdef MSDOS
  28. #include <dir.h>
  29. #include <dos.h>
  30. #endif
  31. #include <fcntl.h>
  32. #include <sys/stat.h>
  33. #include <sys/timeb.h>
  34. #include <string.h>
  35. #include <ctype.h>
  36. #include <time.h>
  37. #include "global.h"
  38. #include "config.h"
  39. #include "timer.h"
  40. #include "proc.h"
  41. #include "bm.h"
  42. #include "files.h"
  43. #include "socket.h"
  44.  
  45. #ifdef linux
  46. extern int unlink __ARGS((char *));
  47. #endif
  48.  
  49. #ifdef UNIX
  50. #define mktime j_mktime
  51. #endif
  52.  
  53. #ifndef __BORLANDC__
  54.  
  55. time_t mktime(struct tm *);
  56.  
  57. /* If you're using BC++ 2.0 or higher, you don't need this,
  58.  * but TCC 2.0 doesn't have it... (But, TC++ v1.01 does)
  59.  */
  60. /* Simple emulation of the mktime() call (sort-of works :-) )
  61.  * doesn't do any error checking,
  62.  * no timezone adjustments or value adjustments
  63.  * Simply 'sort-a' calculates the number of seconds since 1970 - WG7J
  64.  */
  65. time_t
  66. mktime(t)
  67. struct tm *t;
  68. {
  69.     static int total[12]={0,31,59,90,120,151,181,212,243,273,304,334};
  70.     int years;
  71.     int leapyears;
  72.     int days;
  73.  
  74.     /* time count start at jan 1, 1970, 00:00 hrs */
  75.     years = t->tm_year - 70;
  76.     /* adjust for leap-years */
  77.     leapyears = (years + 2) / 4;
  78.     if (!((years+70) & 3) && (t->tm_mon < 2))
  79.     --leapyears;    /* no extra day until 3/1 or after */
  80.  
  81.     days = years*365L + leapyears + total[t->tm_mon] + (t->tm_mday-1);
  82.  
  83.     return( days*86400L + t->tm_hour*3600L + t->tm_min*60L + t->tm_sec);
  84. }
  85.  
  86. #endif
  87.  
  88. /* Include the rest in #ifdef's, so we don't pull in the whole module
  89.  * when we only have AT defined and NOT EXPIRE !
  90.  * (since these are the two modules that needs the surrogate mktime()
  91.  *  if compiling with Turbo C 2.0 )
  92.  */
  93. #ifdef EXPIRY
  94.  
  95. /* Default expiry values: */
  96. #define DEFAULT_AGE 21       /* 21 days from arrival date */
  97. #define MSPHOUR (1000L*60L*60L)
  98. static struct timer Expiretimer;
  99.  
  100. static void Expireprocess __ARGS((int a,void *v1,void *v2));
  101. static void Expiretick __ARGS((void *));
  102. static void expire __ARGS((char *,int));
  103. static void Oldbidtick __ARGS((void *p));
  104.  
  105. int
  106. #ifdef PROTOTYPES
  107. doexpire(int argc,char **argv,void *p)
  108. #else
  109. doexpire(argc,argv,p)
  110. int argc;
  111. char *argv[];
  112. void *p;
  113. #endif
  114. {
  115.     if(argc < 2) {
  116.     tprintf("timer: %lu/%lu hrs\n",
  117.         read_timer(&Expiretimer)/MSPHOUR,
  118.         dur_timer(&Expiretimer)/MSPHOUR);
  119.     return 0;
  120.     }
  121.     if(*argv[1] == 'n') {
  122.     Expiretick(NULL);
  123.     return 0;
  124.     }
  125.     /* set the timer */
  126.     stop_timer(&Expiretimer); /* Just in case */
  127.     Expiretimer.func = (void (*)__FARGS((void*)))Expiretick;/* what to call on timeout */
  128.     Expiretimer.arg = NULL;        /* dummy value */
  129.     set_timer(&Expiretimer,atol(argv[1])*MSPHOUR); /* set timer duration */
  130.     start_timer(&Expiretimer);
  131.     return 0;
  132. }
  133.  
  134. void
  135. Expiretick(p)
  136. void *p;
  137. {
  138.     start_timer(&Expiretimer);
  139.     /* Spawn off the process */
  140.     newproc("Expiry", 1024, Expireprocess, 0, NULL, NULL, 0);
  141. }
  142.  
  143. static void
  144. Expireprocess(a,v1,v2)
  145. int a;
  146. void *v1, *v2;
  147. {
  148.     char line[80];
  149.     int age = DEFAULT_AGE;
  150.     char *cp;
  151.     FILE *ctl;
  152.  
  153.     if ((ctl = fopen(Expirefile, "r")) == NULLFILE) {
  154.     return;
  155.     }
  156.     /* read lines from the control file */
  157.     while(fgets(line, sizeof(line), ctl) != NULLCHAR) {
  158.     pwait(NULL); /* be nice */
  159.     if((*line == '#') || (*line == '\n')) /* comment or blank line */
  160.         continue;
  161.     rip(line);
  162.     /* terminate area name */
  163.     if((cp=strchr(line, ' ')) != NULLCHAR) {
  164.         /* there is age info */
  165.         *cp++ = '\0';
  166.         age = atoi(cp);
  167.     }
  168.     pwait(NULL); /* be nice */
  169.     expire(line,age);
  170.     }
  171.     fclose(ctl);
  172. }
  173.  
  174. void
  175. expire(filename,age)
  176. char *filename;
  177. int age;
  178. {
  179.     char file[128], bckfile[128],*cp;
  180.     char buf[128];
  181.     int keep,copy,expired;
  182.     FILE *old;
  183.     FILE *new;
  184.     long pos;
  185.     time_t now;
  186.     time_t then;
  187.     struct tm t;
  188.  
  189.     /* first replace all '.' and '\' with '/' */
  190.     for(cp=filename;*cp != '\0'; cp++)
  191.     if((*cp == '.') || (*cp == '\\'))
  192.         *cp = '/';
  193.  
  194.     if (mlock(Mailspool,filename)) {
  195.     /* can't get a lock */
  196.     return;
  197.     }
  198.  
  199.     /* now append the 'home dir' in front of name */
  200.     strcpy(file,Mailspool);
  201.     strcat(file,"/");
  202.     strcat(file, filename);
  203.  
  204.     /* get the name for the backup file */
  205.     strcpy(bckfile,file);
  206.     strcat(bckfile,".bak");
  207.     strcat(file,".txt");
  208.  
  209.     /* rename the file */
  210.     unlink(bckfile);
  211.     if(rename(file,bckfile) == -1) {
  212.     rmlock(Mailspool, filename);
  213.     return;
  214.     }
  215.     /* open the backup file and the new txt file */
  216.     if((old = fopen(bckfile, "rt")) == NULLFILE) {
  217.     rmlock(Mailspool, filename);
  218.         return;
  219.     }
  220.     if((new = fopen(file, "wt")) == NULLFILE) {
  221.     rmlock(Mailspool, filename);
  222.         return;
  223.     }
  224.     time(&now);
  225.     copy = expired = 0;
  226.     pos=ftell(old);
  227.     while(fgets(buf,sizeof(buf),old) != NULLCHAR) {
  228.     pwait(NULL);
  229.     if (!strncmp(buf,"From ",5)) {
  230.         /* start of next message; at this point
  231.          * pos has the offset of the start of this line
  232.          */
  233.         keep = copy = 0;
  234.         while(fgets(buf,sizeof(buf),old) != NULLCHAR) {
  235.         if(*buf == '\n')
  236.             break; /* end of headers */
  237.         if(htype(buf) == DATE) {
  238.             /* find age from ARPA style date */
  239.             /* check to see if there is a "Day, " field */
  240.             if((cp=strchr(buf,',')) != NULLCHAR)  {
  241.             /* probably standard ARPA style header */
  242.             cp = &buf[11]; /* get past header and DAY field */
  243.             } else {
  244.             /* probably a NNTP style message, that has no
  245.              * "Day, " part in the date line
  246.              */
  247.              cp = &buf[6];
  248.             }
  249.             /* now we should be at the start of the
  250.              * "14 Apr 92 08:14:32" string
  251.              */
  252.             if(strlen(cp) < 17) /* Too short */
  253.             break;
  254.             t.tm_mday = atoi(cp);
  255.             if(*(++cp) != ' ')
  256.             ++cp;
  257.             ++cp;
  258.             for(t.tm_mon=0; t.tm_mon < 12; t.tm_mon++)
  259.             if(strnicmp(Months[t.tm_mon],cp,3) == 0)
  260.                 break;
  261.             if(t.tm_mon == 12)
  262.             break; /* invalid */
  263.             t.tm_year = atoi(cp+4);
  264.             t.tm_hour = atoi(cp+7);
  265.             t.tm_min = atoi(cp+10);
  266.             t.tm_sec = atoi(cp+13);
  267.             /*
  268.             printf("%d %d %d, %d %d %d\n",
  269.             t.tm_mday,t.tm_mon,t.tm_year,t.tm_hour,t.tm_min,t.tm_sec);
  270.              */
  271.              if((then=mktime(&t)) == -1)
  272.             break; /* invalid, delete */
  273.             /* Now check against age */
  274.             if(now-then < (age*86400L))
  275.             keep = 1;
  276.             break;
  277.         }
  278.         }
  279.         if(keep) {
  280.         /* rewind to start of this message,
  281.          * write from-line and copy the rest
  282.          */
  283.         fseek(old,pos,SEEK_SET);
  284.         fgets(buf,sizeof(buf),old);
  285.         fputs(buf,new);
  286.         copy = 1;
  287.         } else
  288.         expired++;
  289.     } else { /* Any none 'from' line */
  290.         if(copy)
  291.         /* we're in the middle of copying a message */
  292.         fputs(buf,new);
  293.     }
  294.     pos=ftell(old);
  295.     }
  296.     fclose(new);
  297.     fclose(old);
  298.     rmlock(Mailspool,filename);
  299.     if(expired)
  300.     log(-1,"Expired: %d in %s",expired,filename);
  301. }
  302.  
  303.  
  304. /******************************************************************/
  305. /* This program will deleted old BID's from the history file,
  306.  * after making a backup copy.
  307.  *
  308.  *  Eg. 'oldbids 24 30' will try to delete all bids older then 30 days
  309.  *      every 24 hours.
  310.  *      'oldbids now' will do it now, with set value of age.
  311.  *
  312.  * Copyright 1992, Johan. K. Reinalda, WG7J/PA3DIS
  313.  *      email : johan@ece.orst.edu
  314.  *      packet: wg7j@wg7j.or.usa.na
  315.  *
  316.  * Any part of this source may be freely distributed for none-commercial,
  317.  * amateur radio use only, as long as credit is given to the author.
  318.  *
  319.  * v1.0 920325
  320.  */
  321. static struct timer Oldbidtimer;
  322. static int Oldbid_age = 30;
  323.  
  324. static
  325. void
  326. Oldbidtick(p)
  327. void *p;
  328. {
  329.     int expired = 0;
  330.     char *cp;
  331.     FILE *old, *new;
  332.     time_t now;
  333.     time_t age;
  334.     time_t bidtime;
  335.     #define LEN 80
  336.     char oldfile[LEN];
  337.     char buf[LEN];
  338.  
  339.     stop_timer(&Oldbidtimer);
  340.  
  341.     /* delete a previous backup and rename current history file */
  342.     strcpy(oldfile,Historyfile);
  343.     strcat(oldfile,".bak");
  344.     unlink(oldfile);
  345.     if(rename(Historyfile,oldfile) == -1) {
  346.     tputs("oldbid: can't rename history file\n");
  347.     return;
  348.     }
  349.  
  350.     /* open backup for reading, create new history file */
  351.     if((old = fopen(oldfile,"rt")) == NULL) {
  352.     tputs("oldbid: error opening history.bak\n");
  353.     return;
  354.     }
  355.     if((new = fopen(Historyfile,"wt")) == NULL) {
  356.     tputs("oldbid: error creating history file\n");
  357.     return;
  358.     }
  359.  
  360.     now = time(&now);
  361.     age = (time_t)(Oldbid_age*86400L);
  362.  
  363.     while(fgets(buf,LEN,old) != NULL) {
  364.     if((cp=strchr(buf,'\n')) != NULLCHAR)
  365.         *cp = '\0';
  366.     if((cp=strchr(buf,' ')) != NULLCHAR) {
  367.         /*found one with timestamp*/
  368.         *cp = '\0';
  369.         cp++;   /* now points to timestamp */
  370.         if((bidtime = atol(cp)) == 0L)
  371.         /*something wrong, re-stamp */
  372.         fprintf(new,"%s %ld\n",buf,now);
  373.         else {
  374.         /* Has this one expired yet ? */
  375.         if(now - bidtime < age)
  376.             fprintf(new,"%s %ld\n",buf,bidtime);
  377.         else
  378.             expired++;
  379.         }
  380.     } else {
  381.         /* This is an old one without time stamp,
  382.          * add to the new file with current time as timestamp
  383.          */
  384.          fprintf(new,"%s %ld\n",buf,now);
  385.     }
  386.     }
  387.     fclose(old);
  388.     fclose(new);
  389.     if(expired)
  390.     log(-1,"Oldbids: %d expired",expired);
  391.     start_timer(&Oldbidtimer);
  392.     return;
  393. }
  394.  
  395. int
  396. #ifdef PROTOTYPES
  397. dooldbids(int argc,char **argv,void *p)
  398. #else
  399. dooldbids(argc,argv,p)
  400. int argc;
  401. char *argv[];
  402. void *p;
  403. #endif
  404. {
  405.     if(argc < 2){
  406.     tprintf("timer: %lu/%lu hrs; age: %d days\n",
  407.         read_timer(&Oldbidtimer)/MSPHOUR,
  408.         dur_timer(&Oldbidtimer)/MSPHOUR,
  409.         Oldbid_age);
  410.     return 0;
  411.     }
  412.     if(*argv[1] == 'n') {
  413.     Oldbidtick(NULL);
  414.     return 0;
  415.     }
  416.     /* set the timer */
  417.     stop_timer(&Oldbidtimer); /* Just in case */
  418.     Oldbidtimer.func = (void (*)__FARGS((void*)))Oldbidtick;/* what to call on timeout */
  419.     Oldbidtimer.arg = NULL;        /* dummy value */
  420.     set_timer(&Oldbidtimer,atol(argv[1])*MSPHOUR); /* set timer duration */
  421.     if(argc > 2)
  422.     Oldbid_age = atoi(argv[2]);
  423.     Oldbidtick(NULL); /* Do one now and start it all!*/
  424.     return 0;
  425. }
  426.  
  427. #endif /* EXPIRE */
  428.